home *** CD-ROM | disk | FTP | other *** search
/ Video Toaster 4.3 / Video Toaster v4.3.iso / 4.2 / arexx / modeler / pointxform.lwm < prev    next >
Text File  |  1998-04-16  |  5KB  |  189 lines

  1. /* CMD: Transform Points
  2.  * Transform points algorithmically: Swirl,
  3.  * By Arnie Cachelin © 1992, 1993 NewTek Inc.
  4.  */
  5.  
  6. libadd = addlib("LWModelerARexx.port",0)
  7. signal on error
  8. signal on syntax
  9. call addlib "rexxsupport.library", 0, -30, 0
  10. req=0
  11. xf=0
  12. coords.1='z,y,x'
  13. coords.2='x,z,y'
  14. coords.3='x,y,z'
  15. MATHLIB="rexxmathlib.library"
  16. IF POS(MATHLIB , SHOW('L')) = 0 THEN
  17.   IF ~ADDLIB(MATHLIB , 0 , -30 , 0) THEN DO
  18.     call notify(1,"!Can't find "MATHLIB)
  19.     exit
  20.     END
  21. ax=3
  22. rate=90
  23. cx=0
  24. cy=0
  25. cz=0
  26. rmax=1
  27. from=1
  28.  
  29. version = 'XForm v1.0'
  30. filnam = 'ENV:XForm.state'
  31. if (exists(filnam)) then do
  32.     if (~open(state, filnam, 'R')) then break
  33.     if (readln(state) ~= version) then break
  34.     parse value readln(state) with ax rate cx cy cz rmax from .
  35.     call close state
  36. end
  37. call req_begin "Point Transformations"
  38. id_txt = req_addcontrol("Rotate points", 'T',"inside Effect Radius based on")
  39. id_txt = req_addcontrol("their radial", 'T',"positions")
  40. id_Axis = req_addcontrol("Axis", 'CH','X Y Z')
  41. id_cen = req_addcontrol("Center", 'v', 1)
  42. id_rate = req_addcontrol("Rotation Amount (°/m) ", 'n', 0)
  43. id_rad = req_addcontrol("Effect Radius", 'n', 0)
  44. id_from = req_addcontrol("Turn From", 'CH','Center Edge Middle')
  45. xform.1= 'a=a+(rmax-r)*rate' /* Swirl stronger at center */
  46. xform.2= 'a=a+r*rate'        /* Swirl stronger at edge */
  47. xform.3= 'a=a+rmax-2*abs(rmax/2-r)*rate'  /* Swirl strongest at rmax/2 */
  48.  
  49. call req_setval id_Axis, ax
  50. call req_setval id_rate, rate
  51. call req_setval id_cen, cx cy cz, 0.0
  52. call req_setval id_from, from
  53. call req_setval id_rad, rmax, 1.0
  54.  
  55. if (~req_post()) then do
  56.   call req_end
  57.   exit
  58.   end
  59.  
  60. ax= req_getval(id_Axis)
  61. rate=req_getval(id_rate)
  62. parse value req_getval(id_cen) with cx cy cz .
  63. rmax =req_getval(id_rad)
  64. from =req_getval(id_from)
  65.  
  66. call req_end
  67.  
  68. if (open(state, filnam, 'W')) then do
  69.     call writeln state, version
  70.     call writeln state, ax rate cx cy cz rmax from
  71.     call close state
  72. end
  73.  
  74. Pi=3.14159265358
  75. DegreesPerRadian= 180/pi
  76.  
  77. /* Transform loop */
  78. t=time('e')
  79. n = xfrm_begin()
  80. call meter_begin n, 'Transforming 'n' Points'
  81. do i = 1 to n
  82.   parse value xfrm_getpos(i) with dx dy dz .
  83.   x = dx - cx
  84.   y = dy - cy
  85.   z = dz - cz
  86.   interpret 'r=Cyl_R('coords.ax')'
  87.   interpret 'a=Cyl_Theta('coords.ax')'
  88.   interpret 'My_Z='translate(ax,"XYZ","123")
  89. /*   say '#'i ax coords.ax x y z */
  90. /*   say r*1 rmax a'°' My_Z */
  91.   if r>rmax then iterate
  92.   interpret xform.from
  93.   x=Cyl_X(r,a,My_Z)+cx
  94.   y=Cyl_Y(r,a,My_Z)+cy
  95.   z=My_Z+cz
  96.   pos=translate(coords.ax," ",",")
  97. /*   say i '--->' x y z a'°' */
  98.   cmd= 'call xfrm_setpos 'i','pos
  99.     interpret cmd
  100.   call meter_step
  101. end
  102. call meter_end
  103. call xfrm_end
  104. t=time('e')-t
  105. if n>100 then call notify(1,'!Whew, I just transformed 'n' points','!in only 't' seconds.')
  106. if (libadd) then call remlib("LWModelerARexx.port")
  107. exit
  108.  
  109.  
  110. syntax:
  111. error:
  112.   call end_all
  113.     t=Notify(1,'!Rexx Script Error','@'ErrorText(rc),'Line 'SIGL)
  114.   if (libadd) then call remlib("LWModelerARexx.port")
  115.     exit
  116.  
  117. /*
  118.    The following functions convert between 3D cartesian coordinates (X,Y,Z)
  119.    and either cylindrical coordinates (R,Theta,Z) or Spherical
  120.    coordinates (R,Theta,Phi).  The Cylindrical coordinate conversions don't
  121.    take Z inputs, since Z is the same in both cylindical and cartesian systems.
  122.    To go between spherical and cylindrical, use cartesian... or write your own.
  123.     p.s. I lied... see Cyl_Z(), z args are ok now too.
  124.  
  125. */
  126.  
  127.  
  128. /* Return R in Cylindrical coordinate system */
  129. Cyl_R: PROCEDURE
  130.   arg xf, yf, zf
  131.   return sqrt(xf*xf+yf*yf)
  132.  
  133. Cyl_Z: PROCEDURE
  134.   arg xf, yf, zf
  135.   return zf
  136.  
  137. /* Return Theta in Cylindrical coordinate system */
  138. Cyl_Theta: PROCEDURE EXPOSE DegreesPerRadian Pi
  139.   arg x, y, z
  140.     if x=0 then t=sign(y)*90
  141.   else t=DegreesPerRadian*atan(y/x)
  142.     if x<0 then t=t + 180 /* atan() doesn't know which quadrant you're in */
  143.   if t<0 then t=t + 360 /* atan() returns -180 to 180, I like 0 to 360 */
  144.   return t
  145.  
  146. /* Return Cartesian X from Cylindrical coordinate system */
  147. Cyl_X: PROCEDURE EXPOSE DegreesPerRadian
  148.   arg R, Theta, Z
  149.   return R*cos(Theta/DegreesPerRadian)
  150.  
  151. /* Return Cartesian Y from Cylindrical coordinate system */
  152. Cyl_Y: PROCEDURE EXPOSE DegreesPerRadian
  153.   arg R, Theta, Z
  154.   return R*sin(Theta/DegreesPerRadian)
  155.  
  156. /* Return R in Spherical coordinate system */
  157. Sphere_R: PROCEDURE
  158.     arg x, y, z
  159.   return sqrt(x*x+y*y+z*z)
  160.  
  161. /* Return Theta in Spherical coordinate system */
  162. Sphere_Theta: PROCEDURE EXPOSE DegreesPerRadian Pi
  163.   arg x, y, z
  164.     if x=0 then t=sign(y)*90
  165.   else t=DegreesPerRadian*atan(y/x)
  166.     if x<0 then t=t + 180 /* atan() doesn't know which quadrant you're in */
  167.   if t<0 then t=t + 360 /* atan() returns -180 to 180, I like 0 to 360 */
  168.   return t
  169.  
  170. /* Return Phi in Spherical coordinate system */
  171. Sphere_Phi: PROCEDURE EXPOSE DegreesPerRadian Pi
  172.   arg x, y, z
  173.     if z=0 then return 90
  174.     else return DegreesPerRadian*atan(sqrt(x*x+y*y)/z)
  175.  
  176. /* Return Cartesian X from Spherical coordinate system */
  177. Sphere_X: PROCEDURE EXPOSE DegreesPerRadian
  178.   arg R, Theta, Phi
  179.   return R*sin(abs(Phi)/DegreesPerRadian)*cos(Theta/DegreesPerRadian)
  180.  
  181. /* Return Cartesian Y from Spherical coordinate system */
  182. Sphere_Y: PROCEDURE EXPOSE DegreesPerRadian
  183.   arg R, Theta, Phi
  184.   return R*sin(abs(Phi)/DegreesPerRadian)*sin(Theta/DegreesPerRadian)
  185.  
  186. /* Return Cartesian Z from Spherical coordinate system */
  187. Sphere_Z: PROCEDURE EXPOSE DegreesPerRadian
  188.   arg R, Theta, Phi
  189.   return sign(Phi)*R*cos(Phi/DegreesPerRadian)